package cate.game.play.part;

import cate.common.table.d.GDFunc;
import cate.common.table.d.GDPosition;
import cate.common.table.ins.InstanceHeroRow;
import cate.common.table.ins.InstanceRsRow;
import cate.common.util.XT;
import cate.game.play.bg.HeroBg;
import cate.game.play.support.PlayBuildContextWith;
import cate.game.power.PowerFactor;
import cate.game.role.Role;
import cate.game.role.RoleSnapshot;
import cate.game.role.bag.hero.Hero;
import cate.game.role.fight.Position;
import cate.game.role.res.holy_pet.core.HolyPetFightParam;
import cate.game.role.res.leader.hallows.Hallow;
import easy.java.dev.note.NoteClass;
import easy.java.practice.errorcode.EcResult;
import org.apache.commons.lang3.StringUtils;

import java.util.Map;

@NoteClass("战斗一方构建")
public class SideBuilder extends PlayBuildContextWith {


	/**
	 * 根据playSide创建fightSide
	 * @param team
	 * @param ps
	 * @return
	 */
	public FightSide createFightSideByPlaySide(byte team, PlaySide ps) {
		return FightSide.build(ctx, team, ps);
	}


	/**
	 * 根据role创建fightSide
	 * @param team
	 * @param role
	 * @param funcId
	 * @return
	 */
	public EcResult<FightSide> createFightSideByRole(byte team, Role role, int funcId) {
		return createFightSideByRole(team,role,funcId, GDPosition.DEFAULT_POS_NUM);
	}

	public EcResult<FightSide> createFightSideByRole(byte team, Role role, int funcId, int posNum) {
		EcResult<FightSide> r = new EcResult<>();
		EcResult<PlaySide> p_r = createPlaySideByRole(role, funcId,posNum);
		if (!p_r.ok()) {
			return r.fail(p_r.message);
		}
		r.data = createFightSideByPlaySide(team, p_r.data);
		return r.success();
	}


	/**
	 * 根据role自身创建playSide
	 * @param role
	 * @param funcId
	 * @return
	 */
	public EcResult<PlaySide> createPlaySideByRole(Role role, int funcId){
		return createPlaySideByRole(role,funcId,GDPosition.DEFAULT_POS_NUM);
	}
	/**
	 * 根据role自身创建playSide
	 * @param role
	 * @param funcId
	 * @param posNum
	 * @return
	 */
	public EcResult<PlaySide> createPlaySideByRole(Role role, int funcId, int posNum) {
		EcResult<PlaySide> r = new EcResult<>();
		PlaySide side = new PlaySide();
		Position position = role.getFight().getPosition(funcId, posNum);
		if (position == null) {
			return r.fail("请先设置阵型");
		}
		side.snapshot = new RoleSnapshot(role);
		side.positionTid = position.tid;

		if (position.hallowType > 0) {
			Hallow hallow = role.getRes().leader.hallows.getItem(position.hallowType);
			if (hallow != null) {
				side.setHallow(ctx.hallowBuilder().build(role, hallow, false));
				Hallow deputyHallow = role.getRes().leader.hallows.getItem(hallow.deputyType);
				if (deputyHallow != null) {
					side.setDeputyHallow(ctx.hallowBuilder().build(role, deputyHallow, true));
				}
			}
		}

		if (position.holyPetIndex > 0) {
			Map<Integer, HolyPetFightParam> petParams = role.getRes().holyPet.getFightPosition(position.holyPetIndex).getParams();
			for (Map.Entry<Integer, HolyPetFightParam> entry : petParams.entrySet()) {
				BattlePet pet = ctx.petBuilder().build(entry.getValue());
				side.setPets(entry.getKey(), pet);
			}
		}

		PowerFactor powerFactor = new PowerFactor(role, side, funcId);
		position.grids.forEach(
				g -> {
					Hero hero = null;
					switch (g.origin) {
						case GDPosition.Origin.BAG:
							hero = role.getBag().hero.getItem(g.uid);
							break;
						case GDPosition.Origin.SYSTEM:
							switch (funcId){
								case GDFunc.ISLAND:
									hero = role.getFarm().island.record.searchAidHero(g.uid);
									break;
								default:break;
							}
							break;
						case GDPosition.Origin.AID:
							hero = role.getFriend().findAidHero(funcId, g.uid);
							break;
						default:break;
					}
					if (hero != null) {
						BattleHero battleHero = ctx.heroBuilder().buildInPosition(powerFactor, hero, g.pos);
						battleHero.pos = g.pos;
						battleHero.origin = g.origin;
						battleHero.skin = role.getShow().heroSkin.illustrate.getHeroSkin(hero.getTpl(ctx).protoId);
						//背景
						battleHero.bg = new HeroBg(role, hero);
						side.addHero(battleHero);
					}
				});
		if (side.hs.isEmpty()) {
			return r.fail("可以被上阵的英雄数不足1个，无法展开战斗");
		}
		side.updatePower();
		r.data = side;
		return r;
	}



	/**
	 * 通过实例code创建fightSide
	 * @param team
	 * @param code
	 * @return
	 */
	public EcResult<FightSide> createFightSideByCode(byte team, String code) {
		return createFightSideByCode(team,code,0);
	}

	public EcResult<FightSide> createFightSideByCode(byte team, String config, int dynHeroLevel) {
		EcResult<FightSide> r = new EcResult<>();
		EcResult<PlaySide> ps_r = createPlaySideByCode(config, dynHeroLevel);
		if (!ps_r.ok()) {
			return r.fail(ps_r.message);
		}
		r.data = createFightSideByPlaySide(team, ps_r.data);
		return r;
	}

	public EcResult<PlaySide> createPlaySideByCode(String code) {
		return createPlaySideByCode(code, 0);
	}


	public EcResult<PlaySide> createPlaySideByCode(String code, int heroDynLevel) {
		return buildPlaySideByCode(code,heroDynLevel);
	}

	/**
	 * 根据code构建怪物playSide
	 * @param code
	 * @return
	 */
	private EcResult<PlaySide> buildPlaySideByCode(String code, int heroDynLevel) {
		SideCfg sideCfg = new SideCfg(code);
		EcResult<PlaySide> r = new EcResult<>();
		PlaySide side = new PlaySide();
		side.snapshot = buildSnapShot(sideCfg);
		//动态实例
		if (XT.isNotBlank(sideCfg.dynHeroCfg)) {
			for (SideCfg.DynHeroCfg heroCfg : sideCfg.dynHeroCfg) {
				int heroTid = heroCfg.heroTid;
				int heroLevel = heroCfg.level;
				if (heroDynLevel > 0) {
					heroTid += ctx.dynInsExcel().star.getOffSet(heroDynLevel);
					heroLevel = heroDynLevel;
				}
				BattleHero battleHero = ctx.heroBuilder().buildByDynCfg(null, heroTid, heroLevel);
				if (battleHero == null) {
					continue;
				}
				battleHero.skin = heroCfg.skin;
				battleHero.pos = heroCfg.pos;
				battleHero.origin = GDPosition.Origin.SYSTEM;
				side.addHero(battleHero);
			}
		}
		//静态实例
		if (XT.isNotBlank(sideCfg.staticHeroCfg)) {
			for (SideCfg.StaticHeroCfg staticHeroCfg : sideCfg.staticHeroCfg) {
				InstanceHeroRow heroInsTpl = ctx.insExcel().hero.get(staticHeroCfg.insTid);
				if (heroInsTpl != null) {
					BattleHero battleHero = ctx.heroBuilder().buildByInsRow(heroInsTpl);
					if (battleHero != null) {
						battleHero.pos = staticHeroCfg.pos;
						battleHero.origin = GDPosition.Origin.SYSTEM;
						side.addHero(battleHero);
					}
				}
			}
		}
		if (side.hs.isEmpty()) {
			return r.fail("上阵的英雄数不足1个，无法展开战斗");
		}
		side.updatePower();
		r.data = side;
		return r;
	}

	/**
	 * 构建阵容快照
	 * @param code
	 * @return
	 */
	public RoleSnapshot buildSnapShotByCode(String code) {
		return buildSnapShot(new SideCfg(code));
	}

	/**
	 * 构建阵容快照
	 * @param sideCfg
	 * @return
	 */
	private RoleSnapshot buildSnapShot(SideCfg sideCfg) {
		RoleSnapshot snapshot = new RoleSnapshot();
		InstanceRsRow rsRow = ctx.insExcel().rs.get(sideCfg.msInsId);
		if (rsRow != null) {
			snapshot = new RoleSnapshot().readByInstanceRow(rsRow);
		}
		if (StringUtils.isNotBlank(sideCfg.name)) {
			snapshot.base.name = sideCfg.name;
		}
		snapshot.unreal = true;
		return snapshot;
	}

}
